#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Time      :2021/6/24 9:05
# @Author    :cjw
from os.path import exists
from typing import Type, Union
from selenium.webdriver import *
from selenium.webdriver.opera.options import Options as OperaOptions
from selenium.webdriver.edge.options import Options as EdgeOptions

from web_wework.setting import *

BROWSERS = (Chrome, Ie, Firefox, Edge, Opera, PhantomJS, Remote)
OPTIONS = (ChromeOptions, IeOptions, FirefoxOptions, EdgeOptions, OperaOptions)


class BrowserTypeError(Exception):
	"""自定义异常：浏览器类型错误"""

	def __init__(self, _type):
		self._type = _type

	def __repr__(self):
		return f'不支持该浏览器类型：{self._type}'


class BaseBrowser:
	"""浏览器基类"""
	headless = HEADLESS  # 是否无头化启动，默认是False
	implicit_waiting = IMPLICIT_WAIT_TIME  # 隐式等待时间,单位秒
	page_load_time = PAGE_LOAD_TIME  # 页面加载时间，单位秒
	script_timeout = SCRIPT_TIMEOUT  # js执行时间,单位秒
	# windows_size = WINDOWS_SIZE  # 浏览器显示尺寸

	# 浏览器启动路径
	chrome_driver_path = CHROME_DRIVER_PATH
	edge_driver_path = EDGE_DRIVER_PATH
	firefox_driver_path = FIREFOX_DRIVER_PATH

	def __init__(self, browser_type: Type[Union[Chrome, Ie, Firefox, Edge, Opera, PhantomJS, Remote]] = Chrome,
	             option_type: Type[Union[ChromeOptions, IeOptions, FirefoxOptions,
	                                     EdgeOptions, OperaOptions]] = ChromeOptions,
	             driver_path: str = chrome_driver_path,
	             command_executor: str = COMMAND_EXECUTOR):
		"""
		默认使用谷歌浏览器
		:param browser_type: 浏览器类型
		:param option_type: 启动参数类型
		:param driver_path: 驱动路径
		:param command_executor: 远程连接服务URL
		"""
		# 初始化浏览器对象，首先对浏览器类型、参数类型和驱动路径参数进行校验
		if not issubclass(browser_type, BROWSERS):
			raise BrowserTypeError(browser_type)
		if not issubclass(option_type, OPTIONS):
			raise BrowserTypeError(option_type)
		if not exists(driver_path):
			raise FileNotFoundError(f'驱动文件不存在：{driver_path}')

		self._browser = browser_type
		self._option = option_type
		self._driver_path = driver_path
		self._command_executor = command_executor

	@property
	def options(self):
		"""浏览器特定操作，在子类中实现, 用于获取浏览器启动参数"""
		return

	@property
	def browser(self):
		"""启动浏览器，返回浏览器实例"""
		return
